package com.github.llyb120.workflow.entity;

import cn.hutool.core.util.IdUtil;
import com.github.llyb120.workflow.definition.Node;
import lombok.Data;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * 节点树
 * 最下一层是双向链表
 * 严格来说最下一层的定义是不对的，最下表示每个枝叶的末梢
 *
 */
@Data
public class FlowDataLeaf {
    //leafId
    String id;

    //关联日志ID
    String logId;

    String leftLeafId;
    String rightLeafId;

    //子元素
    //为了存储方便只存放ID
    List<String> children = new ArrayList<>();

    Map<String, FlowDataLeaf> cache = new ConcurrentHashMap<>();

    //索引
    String indexLeafId;
//    List<List<String>> levels = new CopyOnWriteArrayList<>();

    //data
    String nodeId;

    /**
     * 主办人，也许将来会出现多个主办人，所以这里使用list
     */
    List<String> handlers = new ArrayList<>();

    /**
     * 观察者
     */
    List<String> observer = new ArrayList<>();


    FlowDataLeaf _getLeaf(String id){
        if (id == null) {
            return null;
        }
        return cache.get(id);
    }

    void add(FlowDataLeaf child){
        //只有root节点可以这么添加
        add(null, child);
    }
    void add(FlowDataLeaf parent, FlowDataLeaf child){
        List<FlowDataLeaf> currents = lastLevel();
        int newLevel;
        if (child.getId() == null) {
            child.setId(IdUtil.objectId());
        }
        //放入map
        cache.put(child.getId(), child);
        if(parent == null){
            //root节点
            indexLeafId = child.getId();
        } else {
            if(currents.contains(parent)){
                if(parent == currents.get(0)){
                    indexLeafId = child.getId();
                }
                child.setLeftLeafId(parent.getLeftLeafId());
                child.setRightLeafId(parent.getRightLeafId());
                FlowDataLeaf sideLeaf = _getLeaf(parent.getLeftLeafId());
                if (sideLeaf != null) {
                    sideLeaf.setRightLeafId(child.getId());
                }
                sideLeaf = _getLeaf(parent.getRightLeafId());
                if (sideLeaf != null) {
                    sideLeaf.setLeftLeafId(child.getId());
                }
                parent.setLeftLeafId(null);
                parent.setRightLeafId(null);
            } else if(currents.isEmpty()){
                //这中情况应该不会出现
                //只有当该叶子是根的时候，才会出现空
                indexLeafId = child.getId();
            } else {
                FlowDataLeaf lastLeaf = currents.get(currents.size() - 1);
                child.setLeftLeafId(lastLeaf.getLeftLeafId());
                lastLeaf.setRightLeafId(child.getId());
            }
            parent.getChildren().add(child.getId());
        }
    }


    /**
     * 获得最后一层的元素，实际上可以当作当前节点
     *
     * @return
     */
    List<FlowDataLeaf> lastLevel(){
        List<FlowDataLeaf> ret = new ArrayList<>();
        FlowDataLeaf start = _getLeaf(indexLeafId);
        if (start == null) {
            return ret;
        }
        ret.add(start);
        while ((start = _getLeaf(start.rightLeafId)) != null){
            ret.add(start);
        }
        return ret;
    }


    @Override
    public String toString() {
        return "FlowDataLeaf{" +
                "id='" + id + '\'' +
                ", logId='" + logId + '\'' +
                ", leftLeafId='" + leftLeafId + '\'' +
                ", rightLeafId='" + rightLeafId + '\'' +
                ", indexLeafId='" + indexLeafId + '\'' +
                ", nodeId='" + nodeId + '\'' +
                '}';
    }


}
